package com.youngjun.user.service.impl;

import com.youngjun.common.exception.CommonExceptionType;
import com.youngjun.common.oss.expection.CommonException;
import com.youngjun.user.mapper.RoleMapper;
import com.youngjun.user.pojo.domain.Role;
import com.youngjun.user.pojo.dto.RoleDTO;
import com.youngjun.user.pojo.dto.query.RoleQueryDTO;
import com.youngjun.user.pojo.vo.RoleVO;
import com.youngjun.user.service.RoleService;
import com.youngjun.user.service.UserRoleService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

@Service
public class RoleServiceImpl implements RoleService {

    @Autowired
    RoleMapper roleMapper;

    @Autowired
    UserRoleService userRoleService;

    @Override
    public RoleMapper getMapper() {
        return roleMapper;
    }

    private List<RoleVO> recursionSuperList(List<RoleVO> list, Long id){
        if(id == null) {
            return list;
        }
        RoleVO vo = selectVO(new Role().setId(id), RoleVO.class);
        list.add(vo);
        return recursionSuperList(list,vo.getParentId());
    }

    private void recursionSubList(List<RoleVO> list, Long id){
        List<RoleVO> voList = selectAllVO(new Role().setParentId(id), RoleVO.class);
        for (RoleVO vo:voList) {
            list.add(vo);
            recursionSubList(list,vo.getId());
        }
    }

    @Override
    public List<RoleVO> queryListByUserId(Long userId) {
        RoleQueryDTO dto =new RoleQueryDTO();
        dto.setUserId(userId);
        dto.setOrganizationId(1459153169673232384L);
        return getMapper().findAll(dto)
                .stream()
                .map(item->new RoleVO().mapFrom(item))
                .collect(Collectors.toList());
    }

    @Override
    public List<RoleVO> queryCurrentRoleList() {
        return queryListByUserId(1459881644986081280L);
    }

    @Override
    public List<RoleVO> queryListByCurrentRole() {
        List<RoleVO> roleList = queryCurrentRoleList();
        List<RoleVO> list = new ArrayList<>(roleList);
        for (RoleVO role:roleList) {
            recursionSubList(list,role.getId());
        }
        return list;
    }

    @Override
    public RoleVO createByCurrentRole(RoleDTO dto) {
        boolean hasPermission=false;
        List<RoleVO> roleList = queryListByCurrentRole();
        for (RoleVO role:roleList){
            if(role.getId().equals(dto.getParentId())){
                hasPermission=true;
                break;
            }
        }
        if(!hasPermission){
            throw new CommonException(CommonExceptionType.DB_INSERT_FAILED);
        }
        Role role = new Role().mapFrom(dto);
        insert(role);
        return new RoleVO().mapFrom(role);
    }

    @Override
    public RoleVO modifyByCurrentRole(RoleDTO dto) {
        boolean hasPermission=false;
        List<RoleVO> roleList = queryListByCurrentRole();
        for (RoleVO role:roleList){
            if(role.getId().equals(dto.getId())&&role.getId().equals(dto.getParentId())){
                hasPermission=true;
                break;
            }
        }
        if(!hasPermission){
            throw new CommonException(CommonExceptionType.DB_UPDATE_FAILED);
        }
        Role role = new Role().mapFrom(dto);
        updateByPrimaryKey(role);
        return new RoleVO().mapFrom(role);
    }

    @Override
    public void deleteByCurrentRole(Long roleId) {
        List<RoleVO> roleList = queryCurrentRoleList();
        List<RoleVO> list = new ArrayList<>(roleList);
        for (RoleVO role:roleList) {
            recursionSuperList(list,role.getParentId());
        }
        for (RoleVO role:list){
            if(roleId.equals(role.getId()) || roleId.equals(role.getParentId())){
                throw new CommonException(CommonExceptionType.DB_DELETE_FAILED);
            }
        }
        delete(roleId);
    }

    @Override
    public List<RoleVO> queryListByCurrentOrganization(RoleQueryDTO dto) {
        dto.setOrganizationId(1459153169673232384L);
        return queryList(dto);
    }

    @Override
    public List<RoleVO> queryList(RoleQueryDTO dto) {
        return selectAllVO(new Role().mapFrom(dto), RoleVO.class);
    }

    @Override
    public RoleVO create(RoleDTO dto) {
        Role role = new Role().mapFrom(dto);
        insert(role);
        return new RoleVO().mapFrom(role);
    }

    @Override
    public RoleVO modify(RoleDTO dto) {
        Role role = new Role().mapFrom(dto);
        updateByPrimaryKey(role);
        return new RoleVO().mapFrom(role);
    }

    @Override
    public void delete(Long roleId) {
        Role role = select(new Role().setId(roleId));
        List<Role> roleList = selectAll(new Role().setParentId(roleId));
        for (Role r:roleList) {
            r.setParentId(role.getParentId());
            updateWithOptionalByPrimaryKey(r);
        }
        deleteWithLogic(roleId);
        userRoleService.deleteByRoleId(roleId);
    }

}